package nl.harmidi.swing;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Polygon;

import nl.harmidi.harmonictable.Spot;
import nl.harmidi.midi.MidiTranslator;
import nl.harmidi.midi.MyMidiEvent;
import nl.harmidi.util.ColorFunctions;
import nl.harmidi.util.Colors;

import org.grlea.log.SimpleLogger;

public class Hexagon {
	private static final long serialVersionUID = 1L;

	private static final SimpleLogger log = new SimpleLogger(Hexagon.class);

	public static enum State {
		ON, OFF
	}

	private String text;

	private State state = State.OFF;

	private int velocity;

	private int x;

	private int y;

	private Color offColor;

	private Color textColor = Colors.TEXT_COLOR;

	private final Color borderColor = Colors.HEXAGON_BORDER;

	private int radius;

	private Polygon outerPolygon;

	private Polygon innerPolygon;

	private final Font font;

	public Hexagon(int x, int y, Spot linkedSpot, int radius) {
		super();
		this.x = x;
		this.y = y;
		this.radius = radius;
		this.text = MidiTranslator.getKeyName(linkedSpot.getNoteNumber());

		this.font= new Font("SansSerif", Font.BOLD, radius/2);
		this.offColor = Colors.getColorFor(text);
		if (!offColor.equals(Color.WHITE)) {
			textColor = Color.WHITE;
		}
		outerPolygon = getPolygon(radius);
		innerPolygon = getPolygon(radius - 1);
		linkedSpot.setLinkedHexagon(this);
		log.ludicrousObject("Hexagon created", this);
	}

	protected void paintComponent(Graphics g) {
		g.setColor(offColor);
		g.fillPolygon(outerPolygon);

		g.setColor(borderColor);
		g.drawPolygon(outerPolygon);

		if (state == State.ON && velocity != 0) {
			double percentage = (Math.round((velocity / 127D) * 100));

			int size = ((int) Math.round((radius * percentage) / 100)) - 1;
			innerPolygon = getPolygon(size);

			g.setColor(ColorFunctions.getGradientColoring(offColor, Colors.HEXAGON_ON, (int) percentage));

			g.drawPolygon(innerPolygon);
			g.fillPolygon(innerPolygon);
		}

		g.setColor(textColor);
//		g.setFont(f);
		g.drawString(text, x - 10, y + 5);
	}

	public Polygon getPolygon(int radius) {
		Polygon p = new Polygon();
		for (int i = 0; i < 6; i++) {
			p.addPoint((int) (x + radius * Math.cos(i * 2 * Math.PI / 6)), (int) (y + radius * Math.sin(i * 2 * Math.PI / 6)));
		}
		return p;
	}

	public void handleNewState(MyMidiEvent event) {
		velocity = event.getVelocity();
		switch (event.getType()) {
		case NOTE_ON:
			state = State.ON;
			break;
		case NOTE_OFF:
			state = State.OFF;
		}
	}

	public void reset() {
		state = State.OFF;
	}

	public int getVelocity() {
		return velocity;
	}

	public void setVelocity(int velocity) {
		this.velocity = velocity;
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	@Override
	public String toString() {
		return String.format("Hexagon ([x=%s][y=%s][text=%s][state=%s][velocity=%s])", x, y, text, state == State.ON ? "ON" : "OFF", velocity);
	}
}
